package agenda;

public class Meeting extends SlottedEntry {

	// @pre isValidDay(day) &&
	// isValidSlot(startSlot) &&
	// (startSlot <= endSlot) && isValidSlot(endSlot)
	protected Meeting(Agenda<?> agenda, Agenda<?> twinAgenda, int day, String subject,
			int firstSlot, int lastSlot) {
		// A precondition should be added here stating that the given
		// agenda's are both effective.
		super(agenda, day, subject);
		if (isValidSlotRange(firstSlot, lastSlot))
			setSlotRange(firstSlot, lastSlot);
		this.twinAgenda = twinAgenda;
		agenda.addEntry(this);
		this.twinAgenda.addEntry(this);
	}
	
	public Meeting(int day, Agenda<? super Meeting> agenda, Agenda<? super Meeting> twinAgenda, String subject,
			int firstSlot, int lastSlot) {
		this(agenda, twinAgenda, day, subject, firstSlot, lastSlot);
	}

	/*** Day */
	@Override
	public boolean canHaveAsDay(int day) {
		return super.canHaveAsDay(day) && (day % 7 != 0);
	}

	/*** slots */
	@Override
	public int getFirstSlot() {
		return this.firstSlot;
	}

	@Override
	public int getLastSlot() {
		return this.lastSlot;
	}

	public static boolean isValidSlotRange(int firstSlot, int lastSlot) {
		return isValidSlot(firstSlot) && isValidSlot(lastSlot)
				&& (firstSlot <= lastSlot);
	}

	@Override
	protected boolean occupiesSlot(int slot) {
		return (slot >= getFirstSlot()) && (slot <= getLastSlot());
	}

	private void setSlotRange(int startSlot, int endSlot) {
		assert isValidSlotRange(startSlot, endSlot);
		this.firstSlot = startSlot;
		this.lastSlot = endSlot;
	}

	private int firstSlot = 1;
	private int lastSlot = 24;

	
	/*** Twin agenda */
	public final Agenda<?> getTwinAgenda() {
		return this.twinAgenda;
	}
	
	private final Agenda<?> twinAgenda;
	

	/*** General purpose */
	public Meeting mergeWith(final Entry other) {
		assert (other != null);
		assert (this.getDay() == other.getDay());
		assert (! this.isTerminated()) && (! other.isTerminated());
		assert (this.getAgenda() == other.getAgenda());
		assert (other instanceof Meeting);
		assert (this.overlapsWith(other));
		Meeting otherMeeting = (Meeting) other;
		this.setSubject(this.getSubject() + other.getSubject());
		this.setSlotRange(Math.min(this.getFirstSlot(),otherMeeting.getFirstSlot()), Math.max(this.getLastSlot(),otherMeeting.getLastSlot()));
		other.terminate();
		return this;
	}

}
